/* 读写🔓，写优先*/
#pragma once

#include <atomic>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

class RWLock {
public:
    RWLock() { std::cout << "RWLock object builded !!!\n"; };
    ~RWLock() { std::cout << "RWLock object destroyed !!!\n"; };
    void acquiredRead();
    void releaseRead();
    void acquiredWrite();
    void releaseWrite();

private:
    std::mutex mtx_;
    std::condition_variable cvRead_;
    std::condition_variable cvWrite_;
    std::atomic<bool> writing_{false};
    volatile int readerCount_ = 0;
};

namespace anotherWay {
class RWLock {
public:
    RWLock() { std::cout << "RWLock object builded !!!\n"; };
    ~RWLock() { std::cout << "RWLock object destroyed !!!\n"; };
    void rlock();
    void wlock();
    void unlock();

private:
    volatile int readBlockedCnt_ = 0;
    volatile int writeBlockedCnt_ = 0;
    /*
     * status_ = -1 : one writer
     * status_ = 0  : no reader and no writer
     * status_ > 0  : no reader
     */
    volatile int status_ = 0;

    std::condition_variable cvRead_;
    std::condition_variable cvWrite_;
    std::mutex mtx_;
};
}  // namespace anotherWay